package puzzle.common.solver;

import puzzle.common.data.AbstractBoard;

public class SolverEvent<B extends AbstractBoard<B>> {
	public enum Type {
		THEORY_RULE, THEORY_STEP, THEORY_WHOLE
	}

	private Type m_type;
	private B m_board;
	private SolverRule<B> m_rule;
	private boolean m_isChanged;

	private SolverEvent(Type type, B b, boolean isChanged) {
		m_type = type;
		m_board = b;
		m_isChanged = isChanged;
	}

	private SolverEvent(Type type, B b, SolverRule<B> rule, boolean isChanged) {
		this(type, b, isChanged);
		m_rule = rule;
	}

	public Type getType() {
		return m_type;
	}

	public B getBoard() {
		return m_board;
	}

	public String getRuleName() {
		if (m_rule != null) {
			return m_rule.getClass().getSimpleName();
		} else {
			return null;
		}
	}

	public boolean isChanged() {
		return m_isChanged;
	}

	public static <B extends AbstractBoard<B>> SolverEvent<B> createTheoryRuleEvent(B b,
			SolverRule<B> rule, boolean isChanged) {
		return new SolverEvent<B>(Type.THEORY_RULE, b, rule, isChanged);
	}

	public static <B extends AbstractBoard<B>> SolverEvent<B> createTheoryStepEvent(B b,
			boolean isChanged) {
		return new SolverEvent<B>(Type.THEORY_STEP, b, isChanged);
	}

	public static <B extends AbstractBoard<B>> SolverEvent<B> createTheoryWholeEvent(B b) {
		return new SolverEvent<B>(Type.THEORY_WHOLE, b, true);
	}

	@Override
	public String toString() {
		return m_type + ", " + m_board + ", " + m_rule + ", " + m_isChanged;
	}
}
